package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.distributor.dto.DistributorCommunicateDeleteBatchDTO;
import com.xbongbong.distributor.vo.DistributorCommunicateDeleteBatchVO;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasListGroupEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataListSearchHelp;
import com.xbongbong.parent.help.ListGroupHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.help.UserHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasListGroupModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonExtraPojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.CallCommunicateDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.UserAndDepartmentGetVO;
import com.xbongbong.paas.service.PaasCommentService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.explain.FormDataDetailFormExplainHandleName;
import com.xbongbong.parent.explain.FormDataListFormExplainHandleName;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.common.pojo.LinkDataPojo;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.RangeScreenConstant;
import com.xbongbong.pro.customer.pojo.dto.CustomerRestoreBatchDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateInsertBatchDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateInsertDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateUpdateBatchDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateUpdateByBusinessRuleDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateUpdateDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.customercommunicate.pojo.vo.CommunicatePermissionVO;
import com.xbongbong.pro.customercommunicate.pojo.vo.CustomerCommunicateInsertBatchVO;
import com.xbongbong.pro.customercommunicate.pojo.vo.CustomerCommunicateUpdateBatchVO;
import com.xbongbong.pro.customercommunicate.pojo.vo.CustomerCommunicateUpdateByBusinessRuleVO;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ContactErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerCommunicateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.message.constant.DistributorCommunicatePushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.service.toolbox.elasticsearch.help.ProEsHelper;
import com.xbongbong.pro.webdetail.pojo.CommunicateLeftDetailPojo;
import com.xbongbong.pro.webdetail.pojo.vo.CommunicateDetailVO;
import com.xbongbong.pro.weblist.pojo.CustomerCommunicatePojo;
import com.xbongbong.pro.weblist.pojo.vo.CommunicateVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ext.CustomerCommunicateEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.ListTopButtonEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RuleSettingEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.CommunicateBaseEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorCommunicateEnum;
import com.xbongbong.saas.enums.business.DistributorContactEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.dictionary.CommunicateTypeEnum;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.CustomerCommunicateModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.DistributorCommunicateService;
import com.xbongbong.saas.service.LikeService;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 经销商跟进记录
 * @author xinpeng.jiang
 * @date 2020/12/30 9:55
 * @version 1.0
 * @since V1.0
 */
@Service("distributorCommunicateServiceImpl")
public class DistributorCommunicateServiceImpl implements DistributorCommunicateService {

    private static final Logger LOG = LoggerFactory.getLogger(DistributorCommunicateServiceImpl.class);

    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private UserModel userModel;
    @Resource
    private CustomerCommunicateModel customerCommunicateModel;
    @Resource
    private PaasCommentService paasCommentService;
    @Resource
    private LikeService likeService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private ListGroupHelp listGroupHelp;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private MessageService messageService;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private ProEsHelper proEsHelper;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;
    @Resource
    private UserHelp userHelp;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private FormDataDetailFormExplainHandleName formDataDetailFormExplainHandleName;
    @Resource
    private FormDataListFormExplainHandleName formDataListFormExplainHandleName;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private PaasListGroupModel paasListGroupModel;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        String corpid = validateDataDTO.getCorpid();
        JSONObject data = validateDataDTO.getData();
        String userId = validateDataDTO.getUserId();
        Long dataId = validateDataDTO.getDataId();
        boolean isNew = false;
        if (dataId == null || dataId == 0) {
            isNew = true;
        }
        saasSaveHelp.formatLinkBusiness4Save(data, DistributorCommunicateEnum.DISTRIBUTOR_NAME.getAttr(), DistributorCommunicateEnum.DISTRIBUTOR_NAME_LINK_TEXT.getAttr(), DistributorCommunicateEnum.DISTRIBUTOR_NAME.getFieldType());
        saasSaveHelp.formatLinkBusiness4Save(data, DistributorCommunicateEnum.CONTACT_ARRAY.getAttr(), DistributorCommunicateEnum.CONTACT_NAME_LINK_TEXT.getAttr(), DistributorCommunicateEnum.CONTACT_ARRAY.getFieldType());
        saasSaveHelp.formatCommunicateBusiness4Save(data, DistributorCommunicateEnum.COMMUNICATE_BUSINESS.getAttr(), DistributorCommunicateEnum.COMMUNICATE_BUSINESS_TYPE.getAttr(), DistributorCommunicateEnum.COMMUNICATE_BUSINESS_LINK_TEXT.getAttr());
        // 时间校验
        checkData(data, isNew);

        Long distributorId = FastJsonHelper.getLongFromFormData(data, DistributorCommunicateEnum.DISTRIBUTOR_NAME.getAttr());
        CustomerEntityExt customerEntityExt = customerModel.getByKey(distributorId, corpid);
        if (customerEntityExt == null) {
            throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201001);
        } else if (customerEntityExt.getDel().equals(1)) {
            throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201001);
        }
        JSONArray contactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, DistributorCommunicateEnum.CONTACT_ARRAY.getAttr(), new JSONArray());
        List<Long> contactIds = contactArr.toJavaList(Long.class);
        if (Objects.nonNull(contactIds) && !contactIds.isEmpty()) {
            List<PaasFormDataEntityExt> paasFormDataEntityExts = paasFormDataEsModel.getByIdList(contactIds, corpid, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CONTACT.getCode(), new ArrayList<>(), IndexTypeEnum.IDX_SAAS_CONTACT);
            if (contactIds.size() != paasFormDataEntityExts.size()) {
                throw new XbbException(ContactErrorCodeEnum.API_ERROR_204006);
            }
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                Long linkDistributorId = FastJsonHelper.getLongOrDefaultFromFormData(paasFormDataEntityExt.getData(), DistributorContactEnum.DISTRIBUTOR_NAME.getAttr(), 0L);
                if (!Objects.equals(linkDistributorId, distributorId)) {
                    throw new XbbException(ContactErrorCodeEnum.API_ERROR_204007);
                }
            }
        }
        if (isNew) {
            data.put(DistributorCommunicateEnum.AUTO_GEN.getAttr(), 0);
            if (Objects.nonNull(data.get(DistributorCommunicateEnum.CREATOR_ID.getAttr()))) {
                userId = data.getString(DistributorCommunicateEnum.CREATOR_ID.getAttr());
            }
            UserEntity userEntity = userModel.getByKeyIngoreDel(userId, corpid);
            if (Objects.isNull(userEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
            }
            if (Objects.nonNull(userEntity)) {
                data.put(DistributorCommunicateEnum.USER_ID.getAttr(), userEntity.getUserId());
                data.put(DistributorCommunicateEnum.USER_NAME.getAttr(), userEntity.getName());
                data.put(DistributorCommunicateEnum.USER_AVATAR.getAttr(), Collections.singletonList(userEntity.getAvatar()));
            }
        }
        for (Map.Entry<String,Object> entry : SaasDataInitHelp.initDistributorCommunicate().entrySet()){
            SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        }
        validateDataDTO.setData(data);
    }

    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        JSONObject data = saasFormSaveDTO.getNewData();
        PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long id = paasFormDataEntity.getId();
        String corpid = paasFormDataEntity.getCorpid();
        String userId = saasFormSaveDTO.getUserId();
        Integer businessType4Distributor = XbbRefTypeEnum.transferBusinessType4Distributor(saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getDistributorMark());
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        Long communicateTime = FastJsonHelper.getLongFromFormData(data, DistributorCommunicateEnum.COMMUNICATE_TIME.getAttr());
        Long customerId = FastJsonHelper.getLongFromFormData(data, DistributorCommunicateEnum.DISTRIBUTOR_NAME.getAttr());

        PaasFormDataEntityExt distributorEntityExt = customerModel.getByKey(customerId,corpid);
        JSONObject distributorData = distributorEntityExt.getData();
        if (saasFormSaveDTO.getIsNew()) {
            if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                String creatorId = paasFormDataEntity.getCreatorId();
                UserEntity creator;
                if (StringUtil.isNotEmpty(creatorId)) {
                    creator = userModel.getByKey(creatorId, corpid);
                } else {
                    creator = userEntity;
                }
                // 跟进记录新建消息推送
                CustomerCommunicateEntityExt customerCommunicateEntityExt = new CustomerCommunicateEntityExt();
                BeanUtil.copyProperties(paasFormDataEntity, customerCommunicateEntityExt);
                List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.DISTRIBUTOR_COMMUNICATE_ADD_PUSH.getCode(), PushTypeEnum.DISTRIBUTOR_COMMUNICATE_ADD_PUSH.getSubCode(), saasFormSaveDTO.getLoginUser(),  customerCommunicateEntityExt);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntity.getAppId(), paasFormDataEntity.getMenuId(), paasFormDataEntity.getFormId(), id, Collections.singletonList(id), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getDistributorMark());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(id), 0, null, I18nMessageUtil.getMessage(DistributorCommunicatePushConstant.DISTRIBUTOR_COMMUNICATE_ADD_TITLE), String.format(I18nMessageUtil.getMessage(DistributorCommunicatePushConstant.DISTRIBUTOR_COMMUNICATE_ADD_CONTENT), creator.getName(), data.getString(DistributorCommunicateEnum.DISTRIBUTOR_NAME_LINK_TEXT.getAttr())), null, options);
                baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_COMMUNICATE_ADD_PUSH, messageRabbitMqDTO);
            }
        }
        // 新建跟进记录中@指定人员
        List<String> atUserIds = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAtUserIds();
        if (Objects.isNull(atUserIds)) {
            JSONObject obj = saasFormSaveDTO.getNewPaasFormDataEntity().getData();
            JSONArray jsonArray = obj.getJSONArray(DistributorCommunicateEnum.AT_USERNAME.getAttr());
            if (Objects.nonNull(jsonArray)) {
                atUserIds = JSONArray.parseArray(jsonArray.toJSONString(),String.class);
            }
        }
        if (Objects.nonNull(atUserIds) && atUserIds.size() > 0) {
            atUserIds.remove(userId);
            pushCustomerCommounicate(saasFormSaveDTO.getLoginUser(), saasFormSaveDTO.getBusinessType(), corpid, atUserIds, paasFormDataEntity, saasFormSaveDTO.getNewPaasFormDataEntity().getId());
        }

        JSONObject jsonObject = new JSONObject();
        if (Long.parseLong(distributorData.getOrDefault(DistributorEnum.LAST_CONNECT_TIME.getAttr(), 0).toString()) < communicateTime) {
            if (communicateTime > DateTimeUtil.getInt()) {
                communicateTime = DateTimeUtil.getInt();
            }
            Boolean flag = paasFormService.getSingleRuleList(corpid, RuleSettingEnum.NEW_FOLLOW_UP_RECORD_VISITING_TIME.getConfig(), distributorEntityExt.getFormId());
            if (flag) {
                jsonObject.put(DistributorEnum.LAST_CONNECT_TIME.getAttr(), communicateTime);
            }

        }
        if (jsonObject.size() > 0) {
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(customerId, jsonObject, corpid);
            customerModel.updateBatch(Collections.singletonList(updateData), corpid);
        }
    }

    @Override
    public void pushCustomerCommounicate(UserVO loginUser, Integer businessType, String corpid, List<String> atUserIds,PaasFormDataEntity paasFormDataEntity, Long dataId) throws XbbException {
        String pushTitle = I18nMessageUtil.getMessage(DistributorCommunicatePushConstant.DISTRIBUTOR_COMMUNICATE_AT_TITLE);
        String pushContent = String.format(I18nMessageUtil.getMessage(DistributorCommunicatePushConstant.DISTRIBUTOR_COMMUNICATE_AT_CONTENT), loginUser.getName(),
                paasFormDataEntity.getData().getString(CommunicateBaseEnum.MAIN_BUSINESS_HIDE.getAttr()));
        PushTypeEnum pushTypeEnum = PushTypeEnum.DISTRIBUTOR_COMMUNICATE_AT_PUSH;

        atUserIds.remove(loginUser.getUserId());
        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntity.getAppId(), paasFormDataEntity.getMenuId(), paasFormDataEntity.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), businessType, businessType,DistributorMarkEnum.DISTRIBUTOR.getCode());
        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, atUserIds, Collections.singletonList(dataId), 0, null, pushTitle, pushContent, null, options);
        baseProducer.sendMessage(pushTypeEnum, messageRabbitMqDTO);
    }

    @Override
    public CommunicateVO list(FormDataListDTO formDataListDTO) throws XbbException {
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(formDataListDTO.getLoginUser(),userEntity);
        // 对移动端的客户名称电话查询作处理
        dealCutomerIdByDingtalk(formDataListDTO);
        saasListDataPermissionHelp.listDataPermission(formDataListDTO.getConditions(),formDataListDTO.getLoginUser(),XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), formDataListDTO.getSubBusinessType());
        if (Objects.equals(formDataListDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
            // app端范围筛选
            saasListDataPermissionHelp.dingtalkRangeScreen(formDataListDTO.getConditions(), userEntity, XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), formDataListDTO.getSubBusinessType(), formDataListDTO.getPlatform());
        } else {
            rangeScreen(formDataListDTO);
        }
        setCondition(formDataListDTO);
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formDataListDTO.getFormId(), formDataListDTO.getCorpid());
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        //表单获取
        PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
        formDataListDTO.setMenuId(paasFormExplainEntity.getMenuId());
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach((item) -> {
            explainMap.put(item.getAttr(), item);
        });
        formDataListDTO.setExplainMap(explainMap);
        //默认排序 字段显示
        formDataListSearchHelp.setListColumn(formDataListDTO);
        Map<String, String> sortMap = formDataListDTO.getSortMap();
        if (Objects.isNull(sortMap) || sortMap.isEmpty()) {
            Map<String, String> defaultSort = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            defaultSort.put("field", CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr());
            defaultSort.put("sort", SortOrder.DESC.name());
            formDataListDTO.setSortMap(defaultSort);
        }
        formDataListDTO.setSearchSubForm(false);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
        PaasFormDataEsListVO formDataListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题 start
        formDataListVO.setForm(form);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO, false);
        handlerExplainDTO.setExplainList(explainList);
        handlerExplainDTO.setPaasFormEntityExt(form);
        HandlerExplainVO handlerExplainVO = formDataListFormExplainHandleName.handleExplain(handlerExplainDTO);
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }

        // 校验联系人字段是否可见
        boolean contactAttrVisible = commonHelp.attrCanSee(CustomerCommunicateEnum.CONTACT_ARRAY.getAttr(), explainMap, handlerExplainDTO);

        formDataListVO.setHeadList(handlerExplainVO.getHeadList());
        formDataListVO.setExplainMap(explainMap);
        formDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
        // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题 end
        List<CustomerCommunicatePojo> customerCommunicatePojoList = new ArrayList<>();
        List<Long> dataIdIn = new ArrayList<>();
        List<PaasFormDataEntityExt> paasFormDataESList = formDataListVO.getPaasFormDataESList();
        if(paasFormDataESList != null && !paasFormDataESList.isEmpty()){
            for (PaasFormDataEntityExt entity : paasFormDataESList) {
                dataIdIn.add(entity.getDataId());
            }
            dataIdIn.add(-1L);
            Map<Long,Integer> commnetCountMap = paasCommentService.getCommnetCountMap(dataIdIn,formDataListDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode());
            Map<Long,Integer> likeCountMap = likeService.getLikeCountMap(dataIdIn,formDataListDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode());
            List<Long> hasCommentIdList = paasCommentService.hasMyComment(dataIdIn,formDataListDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(),formDataListDTO.getUserId());
            List<Long> hasLikeIdList = likeService.hasMyLike(dataIdIn,formDataListDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(),formDataListDTO.getUserId());
            for (PaasFormDataEntityExt entity : paasFormDataESList) {
                JSONObject data = entity.getData();
                Long customerId = data.getLong(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr());
                String customerName = data.getString(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
                String creatorId = data.getString(CustomerCommunicateEnum.USER_ID.getAttr());
                String userName = data.getString(CustomerCommunicateEnum.USER_NAME.getAttr());
                Object userAvatar = data.get(CustomerCommunicateEnum.USER_AVATAR.getAttr());
                try {
                    CustomerCommunicatePojo customerCommunicatePojo = commonHelp.setCommunicatePojo(commnetCountMap, likeCountMap, hasCommentIdList, hasLikeIdList, entity, data, customerId, customerName, creatorId, userName, userAvatar, explainMap, contactAttrVisible, DistributorMarkEnum.DISTRIBUTOR.getCode());
                    customerCommunicatePojoList.add(customerCommunicatePojo);
                } catch (Exception e) {
                    LOG.error("客户跟进保存错误", e);
                }
            }
        }
        CommunicateVO communicateVO = new CommunicateVO();
        communicateVO.setResultMap(customerCommunicatePojoList);
        communicateVO.setPageHelper(formDataListVO.getPageHelper());
        setTopPermissions(formDataListDTO, communicateVO);
        return communicateVO;
    }

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, DistributorCommunicateEnum.COMMUNICATE_TIME.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                saasParticularAttributePoJo.setDateLimit(DateTimeUtil.getTodayInt() + TimeConstant.SECONDS_PER_DAY);
                saasParticularAttributePoJo.setLimitType(true);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            }
        }
    }

    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        customerCommunicateModel.formatUpdateExplainForDistributor(formatExplainDTO);
    }

    @Override
    public CommunicateDetailVO detail(FormDataGetDTO formDataGetDTO) throws XbbException{
        CustomerCommunicateEntityExt entityExt = customerCommunicateModel.getByKey(formDataGetDTO.getDataId(),formDataGetDTO.getCorpid());
        if (Objects.isNull(entityExt) || entityExt.getDel() == 1){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        CommunicateDetailVO communicateDetailVO = new CommunicateDetailVO();
        JSONArray detailPermissionSet = new JSONArray();
        if (formDataGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.DISTRIBUTOR_COMMUNICATE_ADD.getAlias())) {
            detailPermissionSet.add("copy");
        }
        if (formDataGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.DISTRIBUTOR_COMMUNICATE_DELETE.getAlias())) {
            detailPermissionSet.add("del");
        }
        if (formDataGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.DISTRIBUTOR_COMMUNICATE_EDIT.getAlias())) {
            detailPermissionSet.add("edit");
        }
        PaasFormEntityExt paasFormEntity = paasFormModel.getByKey(formDataGetDTO.getFormId(), formDataGetDTO.getCorpid());
        if (paasFormEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        String creatorId = entityExt.getCreatorId();
        //  获取字段解释信息，并且过滤不可见字段 start
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(formDataGetDTO.getFormId(),formDataGetDTO.getCorpid());
        List<FieldAttrEntity> explainList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataGetDTO, handlerExplainDTO, false);
        handlerExplainDTO.setCreatorId(creatorId);
        UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
        BeanUtil.copyProperties(formDataGetDTO, userAndDepartmentGetDTO);
        userAndDepartmentGetDTO.setExplainList(explainList);
        UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO);
        Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
        handlerExplainDTO.setExplainList(explainList);
        // 获取协同人和负责人
        paasFormHelp.getOwnerIdAndCoUserId(handlerExplainDTO, SaasMarkEnum.SAAS.getCode(), formDataGetDTO.getBusinessType(), formDataGetDTO.getSubBusinessType(), entityExt, userMap);

        handlerExplainDTO.setExplainList(explainList);
        handlerExplainDTO.setPaasFormEntityExt(paasFormEntity);
        HandlerExplainVO handlerExplainVO = formDataDetailFormExplainHandleName.handleExplain(handlerExplainDTO);
        if (handlerExplainVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        List<FieldAttrEntity> headList = handlerExplainVO.getHeadList();
        // 获取字段解释信息，并且过滤不可见字段 end
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(headList.size());
        // 将字段放入字段容器
        for (FieldAttrEntity fieldAttrEntity : headList) {
            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
        }

        // 校验联系人字段是否可见
        boolean contactAttrVisible = commonHelp.attrCanSee(DistributorCommunicateEnum.CONTACT_ARRAY.getAttr(), explainMap, handlerExplainDTO);

        Map<String,String> typeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for (FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), CustomerCommunicateEnum.TYPE.getAttr())) {
                List<ItemPoJo> itemList = entity.getItems();
                for (ItemPoJo itemPoJo : itemList) {
                    typeMap.put(itemPoJo.getValue().toString(), itemPoJo.getText());
                }
            }
        }

        communicateDetailVO.setDetailPermissionSet(detailPermissionSet);
        CommunicateLeftDetailPojo communicateLeftDetailPojo = new CommunicateLeftDetailPojo();
        JSONObject data = entityExt.getData();
        // fix: 20935 【跟进记录】跟进记录的表单中将位置字段设置为不可见，手机签到后，跟进记录的详情中仍显示位置信息
        FieldAttrEntity fieldAttrEntity = explainMap.get(DistributorCommunicateEnum.ADDRESS.getAttr());
        if (Objects.isNull(fieldAttrEntity)) {
            data.remove(DistributorCommunicateEnum.ADDRESS.getAttr());
        }
        communicateLeftDetailPojo.setId(entityExt.getId());
        communicateLeftDetailPojo.setCommunicateTime(DateUtil.getString(data.getInteger(DistributorCommunicateEnum.COMMUNICATE_TIME.getAttr())));

        // 先只处理备注，其他字段是否可见，以后需要再处理
        if (explainMap.containsKey(DistributorCommunicateEnum.MEMO.getAttr())) {
            communicateLeftDetailPojo.setMemo(data.getString(DistributorCommunicateEnum.MEMO.getAttr()));
        }
        // 19170 【成功部】点开跟进记录报错
        Object avatar = data.get(DistributorCommunicateEnum.USER_AVATAR.getAttr());
        String userName = data.getString(DistributorCommunicateEnum.USER_NAME.getAttr());
        communicateLeftDetailPojo.setUserId(creatorId);
        communicateLeftDetailPojo.setUserAvatar(avatar);
        communicateLeftDetailPojo.setUserName(userName);
        if(contactAttrVisible){
            communicateLeftDetailPojo.setContact(data.getJSONArray(DistributorCommunicateEnum.CONTACT_NAME_LINK_TEXT.getAttr()));
        }
        if (explainMap.containsKey(DistributorCommunicateEnum.TYPE.getAttr())) {
            setType(communicateLeftDetailPojo, data, explainMap.get(DistributorCommunicateEnum.TYPE.getAttr()));
        }
        communicateLeftDetailPojo.setImages(data.getJSONArray(DistributorCommunicateEnum.IMAGES.getAttr()));
        communicateLeftDetailPojo.setAddress(data.getString(DistributorCommunicateEnum.ADDRESS.getAttr()));
        communicateLeftDetailPojo.setIfLike(likeService.getIfLike(formDataGetDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(),entityExt.getAppId(),entityExt.getId(),creatorId) ? 1 : 0);
        communicateLeftDetailPojo.setCommentCount(paasCommentService.getCount(formDataGetDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(),entityExt.getAppId(),entityExt.getId()));
        communicateLeftDetailPojo.setLikeCount(likeService.getCount(formDataGetDTO.getCorpid(),BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(), entityExt.getAppId(),entityExt.getId(), formDataGetDTO.getUserId()));
        Integer communicateBuisenssType = data.getInteger(CommunicateBaseEnum.COMMUNICATE_BUSINESS_TYPE.getAttr());
        if (!Objects.isNull(communicateBuisenssType)) {
            //方便前端跳转详情
            String businessName = XbbRefTypeEnum.getByCode(XbbRefTypeEnum.transferBusinessType4Distributor(communicateBuisenssType, DistributorMarkEnum.DISTRIBUTOR.getCode())).getName();
            communicateLeftDetailPojo.setCommunicateBusinessName(businessName + "（" + data.getString(DistributorCommunicateEnum.COMMUNICATE_BUSINESS_LINK_TEXT.getAttr()) + "）");
        }
        String customerName = data.getString(DistributorCommunicateEnum.DISTRIBUTOR_NAME_LINK_TEXT.getAttr());
        customerName = customerName == null ? "" : customerName;
        communicateLeftDetailPojo.setMainBusinessName(customerName);
        String addressStr;
        JSONObject addressJsonObject = data.getJSONObject(CommunicateBaseEnum.ADDRESS.getAttr());
        if (Objects.nonNull(addressJsonObject)) {
            try {
                addressStr = addressJsonObject.getString(PaasConstant.PROVINCE) + addressJsonObject.getString(PaasConstant.CITY) + addressJsonObject.getString(PaasConstant.DISTRICT) + addressJsonObject.getString(PaasConstant.ADDRESS);
            }catch (Exception e){
                addressStr = "";
            }
            communicateLeftDetailPojo.setAddress(addressStr);
        }
        communicateDetailVO.setHead(communicateLeftDetailPojo);
        return communicateDetailVO;
    }

    @Override
    public CustomerCommunicateUpdateByBusinessRuleVO updateFormDataByBusinessRule(CustomerCommunicateUpdateByBusinessRuleDTO update) throws XbbException {
        CustomerCommunicateUpdateByBusinessRuleVO resultVO = new CustomerCommunicateUpdateByBusinessRuleVO();
        try {
            String corpid = update.getCorpid();
            List<PaasFormDataEntityExt> formDataList = update.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(update.getFormDataList(), corpid, update.getOperations());

            if(!updateList.isEmpty()){
                customerCommunicateModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(update, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        }catch (Exception e){
            LOG.error("customerCommunicateModel.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return resultVO;
    }

    @Override
    public void autoAfterCallCommunicate(CallCommunicateDTO callCommunicateDTO) throws XbbException {

        // 项目日志
        addCustomerDynamic(callCommunicateDTO.getCorpid(),callCommunicateDTO.getUserId(),callCommunicateDTO.getMemo(),callCommunicateDTO.getCustomerId(),callCommunicateDTO.getCustomerName(), ProjectLogEnum.DISTRIBUTOR_CALL_LOG.getSubType());

        // 是否自动添加跟进记录
        Boolean autoAddComm;
        FormConfigEntity formConfigEntity = formConfigModel.getEntityByBusinessType(callCommunicateDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfig());
        if(formConfigEntity != null) {
            autoAddComm = Objects.equals(formConfigEntity.getConfigValue(), BasicConstant.IS_USE.toString());
        } else {
            autoAddComm = Objects.equals(FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfigValue(), BasicConstant.IS_USE.toString());
        }

        if (!autoAddComm) {
            return;
        }

        // 跟进记录
        String corpid = callCommunicateDTO.getCorpid();
        Long customerId = callCommunicateDTO.getCustomerId();
        String customerName = "";
        if (StringUtil.isNotEmpty(callCommunicateDTO.getCustomerName())) {
            customerName = callCommunicateDTO.getCustomerName();
        }
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),corpid, DistributorMarkEnum.DISTRIBUTOR.getCode(), null);
        Long appId = paasFormEntity.getAppId();
        Long menuId = paasFormEntity.getMenuId();
        Long formId = paasFormEntity.getId();
        if (paasFormEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }

        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }

        Map<String, FieldAttrEntity> explainMapByAttr = ExplainUtil.getExplainMapByAttr(paasFormExplainEntity.getExplains(), CustomerCommunicateEnum.TYPE.getAttr());
        FieldAttrEntity typeFieldAttrEntity = explainMapByAttr.get(CustomerCommunicateEnum.TYPE.getAttr());
        Object typeValue = null;
        if (typeFieldAttrEntity != null) {
            List<ItemPoJo> items = typeFieldAttrEntity.getItems();
            for (ItemPoJo itemPoJo : items) {
                if (Objects.equals(itemPoJo.getValue().toString(), CommunicateTypeEnum.TELEPHONE_CALL.getCode())) {
                    typeValue = itemPoJo.getValue();
                }
            }
        }

        // 生成跟进记录
        CustomerCommunicateEntityExt customerCommunicateEntityExt = new CustomerCommunicateEntityExt();
        JSONObject data = new JSONObject();
        data.put(CommunicateBaseEnum.MEMO.getAttr(),callCommunicateDTO.getMemo());
        data.put(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(),customerId);
        data.put(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(),customerName);
        data.put(CustomerCommunicateEnum.AUTO_GEN.getAttr(),0);
        data.put(CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(),DateTimeUtil.getInt());
        if (Objects.nonNull(typeValue)) {
            data.put(CustomerCommunicateEnum.TYPE.getAttr(), typeValue);
        }
        data.put(CustomerCommunicateEnum.USER_ID.getAttr(), callCommunicateDTO.getUserId());
        data.put(CustomerCommunicateEnum.USER_NAME.getAttr(), callCommunicateDTO.getUserName());
        data.put(CustomerCommunicateEnum.USER_AVATAR.getAttr(), callCommunicateDTO.getUserAvatar());
        if (Objects.nonNull(callCommunicateDTO.getContactId()) && !Objects.equals(callCommunicateDTO.getContactId(), 0L)) {
            data.put(CustomerCommunicateEnum.CONTACT_ARRAY.getAttr(), Collections.singletonList(callCommunicateDTO.getContactId().toString()));
            data.put(CustomerCommunicateEnum.CONTACT_NAME_LINK_TEXT.getAttr(), Collections.singletonList(callCommunicateDTO.getContactName()));
        }
        customerCommunicateEntityExt.setLogType(0);
        customerCommunicateEntityExt.setData(data);
        customerCommunicateEntityExt.setCreatorId(callCommunicateDTO.getUserId());
        customerCommunicateEntityExt.setOwnerId(callCommunicateDTO.getUserId());
        customerCommunicateEntityExt.setCorpid(callCommunicateDTO.getCorpid());
        customerCommunicateEntityExt.setAppId(appId);
        customerCommunicateEntityExt.setMenuId(menuId);
        customerCommunicateEntityExt.setFormId(formId);
        customerCommunicateEntityExt.setSerialNo("");
        customerCommunicateEntityExt.setDepartmentId(0L);
        customerCommunicateEntityExt.setFlowStatus(0);
        try {
            customerCommunicateModel.insert(customerCommunicateEntityExt);
        } catch (Exception e){
            LOG.error("自动添加的跟进记录保存失败",e);
            throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206010);
        }

    }

    @Override
    public DistributorCommunicateDeleteBatchVO deleteBatch(DistributorCommunicateDeleteBatchDTO distributorCommunicateDeleteBatchDTO) throws XbbException {
        DistributorCommunicateDeleteBatchVO distributorCommunicateDeleteBatchVO = new DistributorCommunicateDeleteBatchVO();
        String corpid = distributorCommunicateDeleteBatchDTO.getCorpid();
        try {
            List<Long> deleteIdIn = distributorCommunicateDeleteBatchDTO.getIdIn();
            List<String> name = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> idIn = new ArrayList<>();
            deleteIdIn.forEach(item->{
                if(Objects.nonNull(item)) {
                    idIn.add(item);
                }
            });
            if (!idIn.isEmpty()) {
                //查询编号
                BoolQueryBuilder builder = boolQuery();
                // 添加corpid,formId,del
                builder.filter(termQuery("corpid.keyword", corpid));
                builder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                builder.filter(termsQuery(StringConstant.DATA_ID, idIn));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(CustomerCommunicateEnum.getAttrConnectData(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT));
                List<PaasFormDataEntityExt> nameList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, builder, PaasFormDataEntityExt.class, fieldList);
                for(PaasFormDataEntityExt entityExt : nameList){
                    JSONObject data = entityExt.getData();
                    String cusName = FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), "");
                    name.add(cusName);
                }
                if(BasicConstant.ONE.equals(distributorCommunicateDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(idIn.size())){
                    customerCommunicateModel.deleteByKey(idIn.get(0),corpid);
                }else {
                    customerCommunicateModel.deleteBatch(idIn, corpid);
                }
                distributorCommunicateDeleteBatchVO.setDeleteIds(idIn);
            }
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, distributorCommunicateDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            //生成删除日志(区分单个删除和批量删除)
            String userId = distributorCommunicateDeleteBatchDTO.getUserId();
            String userName = distributorCommunicateDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(name, "，");
            if(idIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getName(), idIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(CustomerCommunicateEnum.CUSTOMER_NAME.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CustomerCommunicate, operateTypeEnum,
                        "", "", memo, distributorCommunicateDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(idIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CustomerCommunicate, operateTypeEnum,
                        idIn.get(0).toString(), nameStr, memo, distributorCommunicateDeleteBatchDTO.getHttpHeader());
            }
        } catch (Exception e) {
            // 回滚
            updateRollback(distributorCommunicateDeleteBatchDTO.getIdIn(), corpid);
            LOG.error("DistributorCommunicateServiceImpl.deleteBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return distributorCommunicateDeleteBatchVO;
    }


    @Override
    public CustomerCommunicateInsertBatchVO insertBatch(CustomerCommunicateInsertBatchDTO insertBatchDTO) throws XbbException {
        CustomerCommunicateInsertBatchVO customerCommunicateInsertBatchVO = new CustomerCommunicateInsertBatchVO();
        try {
            String corpid = insertBatchDTO.getCorpid();
            PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),corpid, DistributorMarkEnum.DISTRIBUTOR.getCode(), null);
            if (Objects.isNull(paasFormEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            List<CustomerCommunicateInsertDTO> customerCommunicateInsertDTOS = insertBatchDTO.getCustomerCommunicateList();
            List<CustomerCommunicateEntityExt> customerCommunicateList = new ArrayList<>();
            String userId = insertBatchDTO.getUserId();
            Long formId = paasFormEntity.getId();
            Long menuId = paasFormEntity.getMenuId();
            Long appId = paasFormEntity.getAppId();
            customerCommunicateInsertDTOS.forEach((item)->{
                CustomerCommunicateEntityExt customerCommunicateEntityExt = new CustomerCommunicateEntityExt();
                BeanUtil.copyProperties(item, customerCommunicateEntityExt);
                JSONObject data = item.getData();
                customerCommunicateEntityExt.setData(data);
                customerCommunicateEntityExt.setCreatorId(userId);
                customerCommunicateEntityExt.setMenuId(menuId);
                customerCommunicateEntityExt.setFormId(formId);
                customerCommunicateEntityExt.setAppId(appId);
                customerCommunicateEntityExt.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
                customerCommunicateEntityExt.setSerialNo("");
                customerCommunicateEntityExt.setDepartmentId(0L);
                customerCommunicateEntityExt.setOwnerId(userId);
                customerCommunicateList.add(customerCommunicateEntityExt);
            });
            if (!customerCommunicateList.isEmpty()) {
                customerCommunicateModel.insertBatch(customerCommunicateList);
            }
        } catch (Exception e) {
            LOG.error("customerCommunicateServiceImpl.insertBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerCommunicateInsertBatchVO;
    }

    @Override
    public List<PaasFormDataEntityExt> getCustomerCommunicateEsDataListByCustomerId(String corpid, Long customerId) throws XbbException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("data." + CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(), customerId));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termQuery(FieldTypeEnum.LOG_TYPE.getAlias(), 0));
        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE;
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.sort(new FieldSortBuilder("data." + CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr()).order(SortOrder.DESC));
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, PaasConstant.ES_MAX_PAGE_SIZE);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest,PaasFormDataEntityExt.class);
        return esEntities.getContent();
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        formDataAddDTO.setSerialNo("");
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);

        FieldAttrEntityForImport linkCustomerAttr = null;
        for (FieldAttrEntityForImport fieldAttrEntityForImport : fieldAttrList) {
            if (Objects.equals(fieldAttrEntityForImport.getAttr(), CustomerCommunicateEnum.CUSTOMER_NAME.getAttr())) {
                linkCustomerAttr = fieldAttrEntityForImport;
                break;
            }
        }

        Long linkCustomerId = 0L;
        if (Objects.nonNull(linkCustomerAttr)) {
            linkCustomerId = importHelper.formatLinkCustomer2CustomerId(titlePojoList, dataJson, rowValueList, linkCustomerAttr);
        }

        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            Integer fieldType = fieldAttr.getFieldType();
            String attrName = fieldAttr.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);
            if (Objects.equals(attr, CustomerCommunicateEnum.CUSTOMER_NAME.getAttr())) {

            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                } else {
                    if (Objects.equals(attr, CommunicateBaseEnum.CONTACT.getAttr())) {
                        importHelper.formatRelyBusiness(linkCustomerId, dataJson, fieldAttr, cellValue, ContactEnum.CUSTOMER_NAME.getAttr());
                    } else if (Objects.equals(attr, CustomerCommunicateEnum.FINISH_COMMUNICATE_PLAN_ID.getAttr())) {
                        importHelper.formatRelyBusiness(linkCustomerId, dataJson, fieldAttr, cellValue, CommunicatePlanEnum.LINK_CUSTOMER.getAttr());
                    } else if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                        formDataAddDTO.setSerialNo(cellValue.toString());
                    } else {
                        dataJson.put(attr, cellValue);
                    }
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        FieldAttrEntity linkCustomerField = new FieldAttrEntity();
        FieldAttrEntity linkBusinessField = new FieldAttrEntity();
        FieldAttrEntity linkContactField = new FieldAttrEntity();
        FieldAttrEntity linkCommunicatePlanField = new FieldAttrEntity();
        FieldAttrEntity linkQuotationField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), CustomerCommunicateEnum.CUSTOMER_NAME.getAttr())) {
                linkCustomerField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CustomerCommunicateEnum.CONTACT_ARRAY.getAttr())) {
                linkContactField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr())) {
                linkBusinessField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), CustomerCommunicateEnum.FINISH_COMMUNICATE_PLAN_ID.getAttr())) {
                linkCommunicatePlanField = fieldAttrEntity;
            }
        }
        Long customerId = 0L;
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                String customerName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CustomerManagementEnum.NAME.getAttr(), "");
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, customerName));
                customerId = linkDataId;
                break;
            case CONTACT:
                String contactName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, ContactEnum.NAME.getAttr(), "");
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, contactName));
                JSONArray linkCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContactEnum.CUSTOMER_NAME.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkCustomerArr));
                saasSaveHelp.formatLinkBusiness4Save(linkFormData, ContactEnum.CUSTOMER_NAME.getAttr(), ContactEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), ContactEnum.CUSTOMER_NAME.getFieldType());
                customerId = FastJsonHelper.getLongOrDefaultFromFormData(linkFormData, ContactEnum.CUSTOMER_NAME.getAttr(), 0L);
                break;
            case SALES_OPPORTUNITY:
                String opportunityNo = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt().getSerialNo();
                opportunityNo = opportunityNo == null ? "" : opportunityNo;
                linkBusinessField.setDefaultAttr(saasUpdateHelp.getDefaultLinkPojo(linkDataId, opportunityNo, redundantTemplateTypeEnum.getCode()));
                JSONArray opportunityLinkCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(opportunityLinkCustomerArr));
                JSONArray contactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.CONTACT_NAME.getAttr(), new JSONArray());
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contactArr));
                saasSaveHelp.formatLinkBusiness4Save(linkFormData, SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), SalesOpportunityEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), SalesOpportunityEnum.CUSTOMER_NAME.getFieldType());
                customerId = FastJsonHelper.getLongOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), 0L);
                break;
            case CONTRACT:
                String contractNo = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt().getSerialNo();
                contractNo = contractNo == null ? "" : contractNo;
                linkBusinessField.setDefaultAttr(saasUpdateHelp.getDefaultLinkPojo(linkDataId, contractNo, redundantTemplateTypeEnum.getCode()));
                JSONArray contractLinkCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CUSTOMER.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractLinkCustomerArr));
                JSONArray contractContactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CONTACT.getAttr(), new JSONArray());
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractContactArr));
                saasSaveHelp.formatLinkBusiness4Save(linkFormData, ContractEnum.LINK_CUSTOMER.getAttr(), ContractEnum.LINK_CUSTOMER_HIDE.getAttr(), ContractEnum.LINK_CUSTOMER.getFieldType());
                customerId = FastJsonHelper.getLongOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CUSTOMER.getAttr(), 0L);
                break;
            case COMMUNICATE_PLAN:
                saasSaveHelp.formatLinkBusiness4Save(linkFormData, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), CommunicatePlanEnum.LINK_CUSTOMER.getFieldType());
                String communicatePlanCustomer = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CommunicatePlanEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), "");
                customerId = FastJsonHelper.getLongOrDefaultFromFormData(linkFormData, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(customerId, communicatePlanCustomer));

                String communicatePlanName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CommunicatePlanEnum.NAME.getAttr(), "");
                linkCommunicatePlanField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, communicatePlanName));
                linkCommunicatePlanField.setEditable(BasicConstant.ZERO);
                break;
            case QUOTATION:
                String quotationNo = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt().getSerialNo();
                linkBusinessField.setDefaultAttr(saasUpdateHelp.getDefaultLinkPojo(linkDataId, quotationNo,redundantTemplateTypeEnum.getCode()));
                /*String quotationName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, QuotationEnum.NAME.getAttr(), "");
                linkBusinessField.setDefaultAttr(saasUpdateHelp.setDefaultAttrPojo4JsonObject(linkDataId, quotationName, redundantTemplateTypeEnum.getCode()));*/
                JSONArray quotationLinkCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, QuotationEnum.CUSTOMER_ID.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(quotationLinkCustomerArr));
                JSONArray quotationContactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, QuotationEnum.CONTACT_ID.getAttr(), new JSONArray());
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(quotationContactArr));
                saasSaveHelp.formatLinkBusiness4Save(linkFormData, QuotationEnum.CUSTOMER_ID.getAttr(), QuotationEnum.CUSTOMER_NAME.getAttr(), QuotationEnum.CUSTOMER_NAME.getFieldType());
                customerId = FastJsonHelper.getLongOrDefaultFromFormData(linkFormData, QuotationEnum.CUSTOMER_ID.getAttr(), 0L);
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
        PaasFormDataEntityExt customer = customerModel.getByKey(customerId, handlerExplainInLinkItemDTO.getCorpid());
        if (customer == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        /*String customerType = FastJsonHelper.getStringOrDefaultFromFormData(customer.getData(), CustomerManagementEnum.TYPE.getAttr(), "");
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), CustomerCommunicateEnum.CUSTOMER_STATUS.getAttr())) {
                List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
                for (ItemPoJo itemPoJo : itemPoJos) {
                    if (Objects.equals(itemPoJo.getValue(), customerType)) {
                        itemPoJo.setChecked(true);
                    } else {
                        itemPoJo.setChecked(false);
                    }
                }
            }
        }*/
    }

    @Override
    public CommunicatePermissionVO permission(BaseDTO baseDTO) throws XbbException{
        CommunicatePermissionVO communicatePermissionVO = new CommunicatePermissionVO();
        JSONArray permissionSet = new JSONArray();
        if (baseDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_COMMUNICATE_ADD.getAlias())) {
            permissionSet.add("add");
        }
        communicatePermissionVO.setPermissionSet(permissionSet);
        return communicatePermissionVO;
    }

    /**
     * 设置头部权限
     *
     * @param formDataListDTO 参数
     * @param communicateVO   回参
     */
    private void setTopPermissions(FormDataListDTO formDataListDTO, CommunicateVO communicateVO) throws XbbException{
        UserVO userVO = formDataListDTO.getLoginUser();
        Integer businessType = formDataListDTO.getBusinessType();
        List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(formDataListDTO.getBusinessType());
        List<ButtonPojo> topButtonList = new ArrayList<>();
        PaasMenuEntity paasMenuEntity = paasMenuModel.getByKey(formDataListDTO.getMenuId(), formDataListDTO.getCorpid());
        if (Objects.isNull(paasMenuEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
        }
        for (ListTopButtonEnum topButtonEnum : topButtonEnumList) {
            if ((Objects.equals(topButtonEnum, ListTopButtonEnum.COMMUNICATE_ADD) && !userVO.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_COMMUNICATE_ADD.getAlias()))
                    || (Objects.equals(topButtonEnum, ListTopButtonEnum.COMMUNICATE_EXPORT) && !userVO.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_COMMUNICATE_EXPORT.getAlias()))
                    || (Objects.equals(topButtonEnum, ListTopButtonEnum.COMMUNICATE_IMPORT) && !userVO.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_COMMUNICATE_IMPORT.getAlias()))) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            BeanUtil.copyProperties(topButtonEnum.getAnEnum(), buttonPojo);
            topButtonList.add(buttonPojo);
            // 移动端列表页新建按钮
            if (Objects.equals(buttonPojo.getAttr(), SaasButtonEnum.ADD.getAttr())) {
                communicateVO.setAddPermission(true);
            }
            if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.IMPORT.getAttr())) {
                ButtonExtraPojo buttonExtraPojo = new ButtonExtraPojo();
                buttonExtraPojo.setImportTitle(paasMenuEntity.getName());
                buttonPojo.setButtonExtra(buttonExtraPojo);
            }
        }
        communicateVO.setTopPermissions(topButtonList);
    }

    /**
     * @param data    数据源
     * @param key     key值
     * @param value   显示值
     * @param isArray 是否是数组存储
     * @return 封装对象
     */
    private List<LinkDataPojo> setData(JSONObject data, String key, String value, Boolean isArray) {
        List<LinkDataPojo> linkDataPojoList = new ArrayList<>();
        String idStr = data.getString(key);
        String nameStr = data.getString(value);
        if (isArray) {
            List<String> keyList = StringUtil.toStringList(idStr, "\\,");
            List<String> nameList = StringUtil.toStringList(nameStr, "\\,");
            if (keyList == null || nameList == null || !Objects.equals(keyList.size(), nameList.size())) {
                return linkDataPojoList;
            }
            Integer index = 0;
            for (String str : keyList) {
                LinkDataPojo linkDataPojo = new LinkDataPojo();
                linkDataPojo.setId(Integer.valueOf(keyList.get(index)));
                linkDataPojo.setName(nameList.get(index));
                linkDataPojoList.add(linkDataPojo);
                index++;
            }
        } else {
            LinkDataPojo linkDataPojo = new LinkDataPojo();
            linkDataPojo.setId(Integer.valueOf(data.getString(key)));
            linkDataPojo.setName(data.getString(value));
            linkDataPojoList.add(linkDataPojo);
        }
        return linkDataPojoList;
    }

    @Override
    public void setCondition(FormDataListDTO formDataListDTO) throws XbbException{
        if(formDataListDTO.getListGroupId() != null){
            PaasListGroupEntity paasListGroupEntity ;
            if (formDataListDTO.getListGroupId() != null && Objects.equals(formDataListDTO.getDefaultGroup(), 0)) {
                paasListGroupEntity = paasListGroupModel.getByKey(formDataListDTO.getListGroupId(), formDataListDTO.getCorpid());
            } else {
                formDataListDTO.setBusinessType(XbbRefTypeEnum.transferBusinessType4Distributor(formDataListDTO.getBusinessType(), formDataListDTO.getDistributorMark()));
                paasListGroupEntity = listGroupHelp.getDefaultGroup(formDataListDTO);
            }
            if (paasListGroupEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.LIST_GROUP_NOT_EXIST);
            }
            List<ConditionsEntityExt> listGroupConditionList = JSONArray.parseArray(paasListGroupEntity.getJsonData(), ConditionsEntityExt.class);
            if(listGroupConditionList != null && !listGroupConditionList.isEmpty()){
                List<ConditionsEntityExt> conditionList = formDataListDTO.getConditions();
                conditionList.addAll(listGroupConditionList);
                formDataListDTO.setConditions(conditionList);
            }
        }

        if (formDataListDTO.getCommonFilter() != null){
            List<ConditionsEntityExt> conditionsEntityExtList = formDataListDTO.getConditions();
            conditionsEntityExtList = conditionsEntityExtList == null ? new ArrayList<>() : conditionsEntityExtList;
            for (Map.Entry<String,Object> entry : formDataListDTO.getCommonFilter().entrySet()){
                if (Objects.isNull(entry.getValue()) || (Objects.nonNull(entry.getValue()) && StringUtil.isEmpty(entry.getValue().toString()))){
                    continue;
                }
                ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
                conditionsEntityExt.setAttr(entry.getKey());
                if (Objects.isNull(CustomerCommunicateEnum.getByAttr(entry.getKey()))) {
                    continue;
                }
                Integer fieldType = CustomerCommunicateEnum.getByAttr(entry.getKey()).getFieldType();
                conditionsEntityExt.setFieldType(fieldType);
                if (Objects.equals(fieldType,FieldTypeEnum.DATETIME.getType())){
                    conditionsEntityExt.setSymbol(ConditionEnum.RANGE.getSymbol());
                    List<String> stringList = JSONArray.parseArray(JSONArray.toJSONString(entry.getValue()),String.class);
                    List<Object> valueList = new ArrayList<>();
                    valueList.add(DateTimeUtil.getInt(stringList.get(0),DateTimeUtil.SDFDate));
                    valueList.add(DateTimeUtil.getInt(stringList.get(1),DateTimeUtil.SDFDate) + TimeConstant.SECONDS_PER_DAY);
                    conditionsEntityExt.setValue(valueList);
                }else if (Objects.equals(fieldType,FieldTypeEnum.COMBO.getType())){
                    conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
                    conditionsEntityExt.setValue(Collections.singletonList(entry.getValue()));
                }else {
                    conditionsEntityExt.setSymbol(ConditionEnum.LIKE.getSymbol());
                    conditionsEntityExt.setValue(Collections.singletonList(entry.getValue()));
                }
                conditionsEntityExtList.add(conditionsEntityExt);
            }
            formDataListDTO.setConditions(conditionsEntityExtList);
        }
        // 添加条件排除“项目日志”
        formDataListDTO.getConditions().add(new ConditionsEntityExt(FieldTypeEnum.LOG_TYPE.getAlias(),"",FieldTypeEnum.LOG_TYPE.getType(),ConditionEnum.EQUAL.getSymbol(),Collections.singletonList(0)));
    }

    /**
     * 校验时间
     *
     * @param data 跟进记录数据
     * @param isNew 是否新建
     * @throws XbbException 业务类型错误
     * @author long.rao
     * @date 2019-05-27 15:06
     */
    private void checkData(JSONObject data, boolean isNew) throws XbbException {
        Long communicateTime = FastJsonHelper.getLongOrDefaultFromFormData(data, CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(), 0L);
        if (Objects.equals(communicateTime, 0L)) {
            throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206004);
        }
        if (communicateTime > DateTimeUtil.getInt()){
            throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206008);
        }
        Integer notifyType = FastJsonHelper.getIntegerOrDefaultFromFormData(data, CustomerCommunicateEnum.NOTIFY_TYPE.getAttr(), CommunicatePlanNotifyTypeEnum.NO_NOTIFY.getCode());
        Long notifyTime = 0L;
        Long nextCommunicateTime = FastJsonHelper.getLongOrDefaultFromFormData(data, CustomerCommunicateEnum.NEXT_COMMUNICATE_TIME.getAttr(), 0L);
        Integer ifRemind = FastJsonHelper.getIntegerOrDefaultFromFormData(data, CustomerCommunicateEnum.IF_REMIND.getAttr(), BasicConstant.ZERO);
        CommunicatePlanNotifyTypeEnum communicatePlanNotifyTypeEnum = CommunicatePlanNotifyTypeEnum.getByCode(notifyType);
        if (Objects.equals(ifRemind, BasicConstant.ONE)) {
            switch (communicatePlanNotifyTypeEnum) {
                case ADVANCE_ONE_QUARTER_HOUR:
                    notifyTime = nextCommunicateTime - TimeConstant.SECONDS_PER_MINUTE * 15;
                    break;
                case ADVANCE_ONE_HOUR:
                    notifyTime = nextCommunicateTime - TimeConstant.SECONDS_PER_HOUR;
                    break;
                case ADVANCE_ONE_DAY:
                    notifyTime = nextCommunicateTime - TimeConstant.SECONDS_PER_DAY;
                    break;
                case ADVANCE_THREE_DAY:
                    notifyTime = nextCommunicateTime - TimeConstant.SECONDS_PER_DAY * 3;
                    break;
                case ADVANCE_ONE_WEEK:
                    notifyTime = nextCommunicateTime - TimeConstant.SECONDS_PER_WEEK;
                    break;
                case CUSTOM_TIME:
                    notifyTime = FastJsonHelper.getLongOrDefaultFromFormData(data, CustomerCommunicateEnum.NOTIFY_TIME.getAttr(), 0L);
                    break;
                default:
                    notifyTime = nextCommunicateTime;
                    break;
            }
            if (isNew) {
                if (notifyTime == null || notifyTime <= DateTimeUtil.getInt()) {
                    throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206009);
                }
                if (notifyTime > nextCommunicateTime) {
                    throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206011);
                }
            }
            data.put(CustomerCommunicateEnum.NOTIFY_TIME.getAttr(), notifyTime);
        }
    }

    /**
     * 下次跟进提醒保存
     *
     * @param corpid
     * @param customer
     * @param saasFormSaveDTO
     * @throws
     * @author long.rao
     * @date 2019-05-27 17:24
     */
    private void remindSave(String corpid, PaasFormDataEntityExt customer, SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        Long refId = customer.getId();
        String userId = saasFormSaveDTO.getUserId();
        List<String> userIds = Collections.singletonList(userId);
        List<Long> refIds = Collections.singletonList(refId);
        JSONObject newData = saasFormSaveDTO.getNewData();
        PushRefTypePojo.Options options = new PushRefTypePojo.Options(customer.getAppId(), customer.getMenuId(), customer.getFormId(), refId, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());

        Long notifyTime = FastJsonHelper.getLongOrDefaultFromFormData(newData, CustomerCommunicateEnum.NOTIFY_TIME.getAttr(), 0L);
        String content = FastJsonHelper.getStringOrDefaultFromFormData(newData, CustomerCommunicateEnum.NEXT_NOTIFY_MEMO.getAttr(), "");

        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, userIds, refIds, 1, notifyTime, XbbRefTypeEnum.PUSH_NOTIFY.getName(), content, null, options);
        messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.CUSTOMER_PUSH);
    }

    /**
     * 下次跟进提醒新建访客计划
     *
     * @param corpid 公司id
     * @param saasFormSaveDTO 保存DTO
     * @throws XbbException
     * @author long.rao
     * @date 2019-05-27 18:10
     */
    private void joinCommunicatePlan(String corpid, SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONArray customerArr = new JSONArray();
        JSONObject customerObj = new JSONObject();
        customerObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, FastJsonHelper.getLongOrDefaultFromFormData(newData, CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(), 0L));
        customerObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(newData, CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), ""));
        customerArr.add(customerObj);
        Long nextCommunicateTime = FastJsonHelper.getLongOrDefaultFromFormData(newData, CustomerCommunicateEnum.NEXT_COMMUNICATE_TIME.getAttr(), 0L);
        String notifyTypeMemo = FastJsonHelper.getStringOrDefaultFromFormData(newData, CustomerCommunicateEnum.NEXT_NOTIFY_MEMO.getAttr(), "");
        JSONObject planDataList = new JSONObject();

        FormDataAddDTO planAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(saasFormSaveDTO, planAddDTO);
        PaasFormExplainEntity planExplain = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), corpid);
        BeanUtil.copyProperties(planExplain, planAddDTO);
        planDataList.put(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerArr);
        planDataList.put(CommunicatePlanEnum.EXECUTOR.getAttr(), Collections.singletonList(ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode()));
        JSONObject executorObj = new JSONObject();
        executorObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, saasFormSaveDTO.getUserId());
        JSONArray executorArr = new JSONArray();
        executorArr.add(executorObj);
        planDataList.put(CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), executorArr);
        planDataList.put(CommunicatePlanEnum.TARGET.getAttr(), "");
        planDataList.put(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr(), nextCommunicateTime);
        planDataList.put(CommunicatePlanEnum.NOTIFY_TYPE.getAttr(), FastJsonHelper.getIntegerOrDefaultFromFormData(newData, CustomerCommunicateEnum.NOTIFY_TYPE.getAttr(), 0));
        planDataList.put(CommunicatePlanEnum.NOTIFY_TIME.getAttr(), FastJsonHelper.getIntegerOrDefaultFromFormData(newData, CustomerCommunicateEnum.NOTIFY_TIME.getAttr(), BasicConstant.ZERO));
        planDataList.put(CommunicatePlanEnum.MEMO.getAttr(), notifyTypeMemo);
        planAddDTO.setDataList(planDataList);
        planAddDTO.setSerialNo("");
        planAddDTO.setCorpid(corpid);
        planAddDTO.setUserId(saasFormSaveDTO.getUserId());
        planAddDTO.setBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
        listBatchService.joinCommunicatePlan(planAddDTO);
    }

    @Override
    public void dataConsistencyUpdateCustomer(String corpid, Long customerId, String customerName) throws XbbException {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.CUSTOMER_NAME), customerId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<CustomerCommunicateEntityExt> customerCommunicateEntityExtList = customerCommunicateModel.findEntitys(param);

            if (Objects.nonNull(customerCommunicateEntityExtList) && !customerCommunicateEntityExtList.isEmpty()) {
                List<CustomerCommunicateUpdateDTO> customerCommunicateUpdateDTOList = new ArrayList<>();
                for (CustomerCommunicateEntityExt entityExt : customerCommunicateEntityExtList) {
                    CustomerCommunicateUpdateDTO customerCommunicateUpdateDTO = new CustomerCommunicateUpdateDTO();
                    customerCommunicateUpdateDTO.setId(entityExt.getId());
                    JSONObject data = new JSONObject();
                    data.put(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), customerName);
                    customerCommunicateUpdateDTO.setData(data);
                    customerCommunicateUpdateDTOList.add(customerCommunicateUpdateDTO);
                }
                CustomerCommunicateUpdateBatchDTO customerCommunicateUpdateBatchDTO = new CustomerCommunicateUpdateBatchDTO();
                customerCommunicateUpdateBatchDTO.setCorpid(corpid);
                customerCommunicateUpdateBatchDTO.setCommunicateUpdateList(customerCommunicateUpdateDTOList);
                updateBatch(customerCommunicateUpdateBatchDTO);
            }

        } catch (Exception e) {
            LOG.error("CustomerCommunicateServiceImpl.dataConsistencyUpdateCustomer 出错，corpid=" + corpid + "  customerId=" + customerId + " customerName=" + customerName, e);
        }
    }

    @Override
    public CustomerCommunicateUpdateBatchVO updateBatch(CustomerCommunicateUpdateBatchDTO customerCommunicateUpdateBatchDTO) throws XbbException {
        CustomerCommunicateUpdateBatchVO customerCommunicateUpdateBatchVO = new CustomerCommunicateUpdateBatchVO();
        try {
            String corpid = customerCommunicateUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<CustomerCommunicateUpdateDTO> customerCommunicateUpdateList = customerCommunicateUpdateBatchDTO.getCommunicateUpdateList();
            if (Objects.nonNull(customerCommunicateUpdateList) && !customerCommunicateUpdateList.isEmpty()) {
                customerCommunicateUpdateList.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                customerCommunicateModel.updateBatch(updateList, corpid);
            }
        } catch (Exception e) {
            LOG.error("CustomerCommunicateServiceImpl.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerCommunicateUpdateBatchVO;
    }

    @Override
    public void dataConsistencyUpdateLinkBusiness(String corpid, Long dataId, String serialNo, Integer businessType) throws XbbException {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.COMMUNICATE_BUSINESS), dataId))
                    .filter(termQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_TYPE), businessType));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<CustomerCommunicateEntityExt> customerCommunicateEntityExtList = customerCommunicateModel.findEntitys(param);

            if (Objects.nonNull(customerCommunicateEntityExtList) && !customerCommunicateEntityExtList.isEmpty()) {
                List<CustomerCommunicateUpdateDTO> customerCommunicateUpdateDTOList = new ArrayList<>();
                for (CustomerCommunicateEntityExt entityExt : customerCommunicateEntityExtList) {
                    CustomerCommunicateUpdateDTO customerCommunicateUpdateDTO = new CustomerCommunicateUpdateDTO();
                    customerCommunicateUpdateDTO.setId(entityExt.getId());
                    JSONObject data = new JSONObject();
                    data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_LINK_TEXT.getAttr(), serialNo);
                    customerCommunicateUpdateDTO.setData(data);
                    customerCommunicateUpdateDTOList.add(customerCommunicateUpdateDTO);
                }
                CustomerCommunicateUpdateBatchDTO customerCommunicateUpdateBatchDTO = new CustomerCommunicateUpdateBatchDTO();
                customerCommunicateUpdateBatchDTO.setCorpid(corpid);
                customerCommunicateUpdateBatchDTO.setCommunicateUpdateList(customerCommunicateUpdateDTOList);
                updateBatch(customerCommunicateUpdateBatchDTO);
            }

        } catch (Exception e) {
            LOG.error("CustomerCommunicateServiceImpl.dataConsistencyUpdateOpportunity 出错， corpid=" + corpid + " dataId=" + dataId + "  opportunityName=" + serialNo, e);
        }
    }

    @Override
    public void addCustomerDynamic(CustomerDynamicAddDTO customerDynamicAddDTO) throws XbbException{
        String corpid = customerDynamicAddDTO.getCorpid();
        Long customerId = customerDynamicAddDTO.getCustomerId();
        String customerName = customerDynamicAddDTO.getCustomerName();
        if (StringUtil.isEmpty(customerDynamicAddDTO.getCustomerName())) {
            //获取客户数据
            PaasFormDataEntityExt paasFormDataEntityExt = customerModel.getByKey(customerId, corpid);
            if (paasFormDataEntityExt != null) {
                customerName =  paasFormDataEntityExt.getData().getString(CustomerManagementEnum.NAME.getAttr());
            }
        }
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),corpid, customerDynamicAddDTO.getDistributorMark(), null);
        Long appId = 0L;
        Long menuId = 0L;
        Long formId = 0L;
        if (paasFormEntity != null) {
            appId = paasFormEntity.getAppId();
            menuId = paasFormEntity.getMenuId();
            formId = paasFormEntity.getId();
        }
        // 保存入库
        CustomerCommunicateEntityExt customerCommunicateEntityExt = new CustomerCommunicateEntityExt();
        JSONObject data = new JSONObject();
        data.put(CommunicateBaseEnum.MEMO.getAttr(),customerDynamicAddDTO.getMemo());
        data.put(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(),customerId);
        data.put(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(),customerName);
        data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr(),customerDynamicAddDTO.getDataId());
        data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_TYPE.getAttr(),customerDynamicAddDTO.getCommunicateBusinessType());
        data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_LINK_TEXT.getAttr(),customerDynamicAddDTO.getCommunicateBusinessText());
        data.put(CustomerCommunicateEnum.AUTO_GEN.getAttr(),1);
        data.put(CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(),DateTimeUtil.getInt());
        customerCommunicateEntityExt.setLogType(customerDynamicAddDTO.getLogType());
        customerCommunicateEntityExt.setData(data);
        customerCommunicateEntityExt.setCreatorId(customerDynamicAddDTO.getUserId());
        customerCommunicateEntityExt.setOwnerId(customerDynamicAddDTO.getUserId());
        customerCommunicateEntityExt.setCorpid(customerDynamicAddDTO.getCorpid());
        customerCommunicateEntityExt.setAppId(appId);
        customerCommunicateEntityExt.setMenuId(menuId);
        customerCommunicateEntityExt.setFormId(formId);
        customerCommunicateEntityExt.setSerialNo("");
        customerCommunicateEntityExt.setDepartmentId(0L);
        customerCommunicateEntityExt.setFlowStatus(0);
        try {
            customerCommunicateModel.insert(customerCommunicateEntityExt);
        } catch (Exception e){
            LOG.error("项目日志保存失败",e);
            throw new XbbException(CustomerCommunicateErrorCodeEnum.API_ERROR_206012);
        }
    }

    @Override
    public void addCustomerDynamic(String corpid,String userId,String memo,Long customerId,String customerName,Integer logType) throws XbbException{
        CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
        customerDynamicAddDTO.setCorpid(corpid);
        customerDynamicAddDTO.setUserId(userId);
        customerDynamicAddDTO.setMemo(memo);
        customerDynamicAddDTO.setCustomerId(customerId);
        customerDynamicAddDTO.setCustomerName(customerName);
        customerDynamicAddDTO.setDataId(0L);
        customerDynamicAddDTO.setCommunicateBusinessType(null);
        customerDynamicAddDTO.setCommunicateBusinessText("");
        customerDynamicAddDTO.setLogType(logType);
        customerDynamicAddDTO.setDistributorMark(DistributorMarkEnum.DISTRIBUTOR.getCode());
        addCustomerDynamic(customerDynamicAddDTO);
    }

    @Override
    public void batchAddCustomerDynamic(List<CustomerDynamicAddDTO> list,String corpid) throws XbbException{
        if (list == null || list.isEmpty()) {
            return;
        }
        List<CustomerCommunicateEntityExt> entityExtList = new ArrayList<>();
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),corpid, DistributorMarkEnum.DISTRIBUTOR.getCode(), null);
        Long appId = 0L;
        Long menuId = 0L;
        Long formId = 0L;
        if (paasFormEntity != null) {
            appId = paasFormEntity.getAppId();
            menuId = paasFormEntity.getMenuId();
            formId = paasFormEntity.getId();
        }
        for (CustomerDynamicAddDTO customerDynamicAddDTO : list) {
            Long customerId = customerDynamicAddDTO.getCustomerId();
            String customerName = customerDynamicAddDTO.getCustomerName();
            if (StringUtil.isEmpty(customerDynamicAddDTO.getCustomerName())) {
                //获取客户数据
                PaasFormDataEntityExt paasFormDataEntityExt = customerModel.getByKey(customerId, corpid);
                if (paasFormDataEntityExt != null) {
                    customerName =  paasFormDataEntityExt.getData().getString(CustomerManagementEnum.NAME.getAttr());
                }
            }
            // 保存入库
            CustomerCommunicateEntityExt customerCommunicateEntityExt = new CustomerCommunicateEntityExt();
            JSONObject data = new JSONObject();
            data.put(CommunicateBaseEnum.MEMO.getAttr(),customerDynamicAddDTO.getMemo());
            data.put(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr(),customerId);
            data.put(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(),customerName);
            data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS.getAttr(),customerDynamicAddDTO.getDataId());
            data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_TYPE.getAttr(),customerDynamicAddDTO.getCommunicateBusinessType());
            data.put(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_LINK_TEXT.getAttr(),customerDynamicAddDTO.getCommunicateBusinessText());
            data.put(CustomerCommunicateEnum.AUTO_GEN.getAttr(),1);
            data.put(CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(),DateTimeUtil.getInt());
//            data.put(CustomerCommunicateEnum.TYPE.getAttr(), CommunicateTypeEnum.PROJECT_LOG.getCode());
            customerCommunicateEntityExt.setLogType(customerDynamicAddDTO.getLogType());
            customerCommunicateEntityExt.setData(data);
            customerCommunicateEntityExt.setCreatorId(customerDynamicAddDTO.getUserId());
            customerCommunicateEntityExt.setOwnerId(customerDynamicAddDTO.getUserId());
            customerCommunicateEntityExt.setCorpid(customerDynamicAddDTO.getCorpid());
            customerCommunicateEntityExt.setAppId(appId);
            customerCommunicateEntityExt.setMenuId(menuId);
            customerCommunicateEntityExt.setFormId(formId);
            customerCommunicateEntityExt.setSerialNo("");
            customerCommunicateEntityExt.setDepartmentId(0L);
            customerCommunicateEntityExt.setFlowStatus(0);
            customerCommunicateEntityExt.setAddTime(DateTimeUtil.getInt());
            customerCommunicateEntityExt.setUpdateTime(DateTimeUtil.getInt());
            entityExtList.add(customerCommunicateEntityExt);
        }
        try {
            customerCommunicateModel.insertBatch(entityExtList);
        } catch (Exception e) {
            LOG.error("项目日志批量保存失败",e);
        }
    }

    /**
     * 更新时回滚
     * @param idIn
     * @param corpid
     * @throws XbbException
     */
    @Override
    public void updateRollback(List<Long> idIn, String corpid) throws XbbException {
        if (Objects.isNull(idIn) || idIn.isEmpty()) {
            return;
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", idIn);
        param.put(StringConstant.CORPID, corpid);
        List<CustomerCommunicateEntityExt> communicateList = customerCommunicateModel.findEntitysWithoutSub(param);
        if (Objects.nonNull(communicateList)) {
            for (CustomerCommunicateEntityExt item : communicateList) {
                PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
                BeanUtil.copyProperties(item, paasFormDataEntity);
                proEsHelper.reductionEsInUpdate(paasFormDataEntity, item.getId(), corpid, IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE);
            }
        }
    }

    /**
     * 还原数据
     * @author xingxing.xiao
     * @date 2019/09/17 14:00
     */
    @Override
    public void restoreBatch(String corpid, Map<Long, Long> customerUpdateTimeMap, CustomerRestoreBatchDTO customerRestoreBatchDTO) throws XbbException {
        try {
            // 根据客户的 id 和 updateTime 来查询要还原的数据
            List<Long> dataIdList = new ArrayList<>();
            List<String> customerNames = new ArrayList<>();
            BoolQueryBuilder booleanQuery = boolQuery();
            booleanQuery.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            booleanQuery.filter(termQuery(StringConstant.DEL, DelEnum.DELETE.getDel()));
            for (Map.Entry<Long, Long> entry : customerUpdateTimeMap.entrySet()) {
                BoolQueryBuilder shouldQueryBuilder = boolQuery();
                shouldQueryBuilder.filter(termsQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.CUSTOMER_NAME), entry.getKey().toString()));
                shouldQueryBuilder.filter(rangeQuery(CustomerCommunicateEnum.UPDATE_TIME.getAttr()).gte(entry.getValue()));
                booleanQuery.should(shouldQueryBuilder);
            }
            booleanQuery.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
            List<String> fieldList = new ArrayList<>();
            fieldList.add(StringConstant.SAAS_LINK_BUSINESS_ID);
            fieldList.add(CustomerCommunicateEnum.getAttrConnectData(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT));
            List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, booleanQuery, PaasFormDataEntityExt.class, fieldList);
            paasFormDataEntityExtList.forEach(item -> {
                dataIdList.add(item.getId());
                customerNames.add(item.getData().getString(CustomerCommunicateEnum.CUSTOMER_NAME_LINK_TEXT.getAttr()));
            });
            if (dataIdList.isEmpty()) {
                return;
            }
            customerCommunicateModel.restoreBatch(dataIdList, corpid, DelEnum.NORMAL.getDel());
            // 日志
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.REVERT_CANCEL;
            String nameStr = StringUtils.join(customerNames, "，");
            String userName = customerRestoreBatchDTO.getLoginUserName();
            String userId = customerRestoreBatchDTO.getUserId();
            if(dataIdList.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_REVERT_FORM_DETAIL), userName, operateTypeEnum.getName(), customerNames.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(CustomerCommunicateEnum.CUSTOMER_NAME.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CustomerCommunicate, operateTypeEnum,
                        "", "", memo, customerRestoreBatchDTO.getHttpHeader());
            } else if(Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CustomerCommunicate, operateTypeEnum,
                        dataIdList.get(0).toString(), nameStr, memo, customerRestoreBatchDTO.getHttpHeader());
            }
        } catch (Exception e){
            LOG.error("customerCommunicateServiceImpl.restoreBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 对移动端的客户名称电话查询作处理 (客户表中名称电话模糊查询)
     * @param formDataListDTO
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/10/28 11:32
     */
    private void dealCutomerIdByDingtalk(FormDataListDTO formDataListDTO) throws XbbException {
        List<ConditionsEntityExt> conditionsList = formDataListDTO.getConditions();
        for (ConditionsEntityExt conditionsEntityExt : conditionsList) {
            if (Objects.equals(conditionsEntityExt.getAttr(), "nameLike")) {
                String nameLike = conditionsEntityExt.getValue().get(0).toString();
                List<Object> customerIdIn = new ArrayList<>();
                if (nameLike != null && !StringUtil.isEmpty(nameLike, true)) {
                    BoolQueryBuilder nameLikeQuery = boolQuery();
                    nameLikeQuery.filter(termQuery("corpid.keyword", formDataListDTO.getCorpid()));
                    nameLikeQuery.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
                    EsUtil.setNameLike(SaasMarkEnum.SAAS.getCode(), nameLike, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), false, nameLikeQuery,true,null,null);
                    IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(formDataListDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

                    List<PaasFormDataEntityExt> customerList = esHelper.findByScroll(indexTypeEnum,nameLikeQuery,PaasFormDataEntityExt.class,Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
                    customerList.forEach(item ->{
                        customerIdIn.add(item.getDataId());
                    });
                    if (customerIdIn.isEmpty()) {
                        customerIdIn.add(-1);
                    }
                    conditionsEntityExt.setAttr(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr());
                    conditionsEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
                    conditionsEntityExt.setValue(new ArrayList<>(customerIdIn));
                }
            }
        }
    }

    /**
     * 设置跟进记录的跟进方式
     *
     * @param communicateDetailPojo
     * @param data
     * @param typeField
     * @author long.rao
     * @date 2020/02/19 11:15
     */
    private void setType(CommunicateLeftDetailPojo communicateDetailPojo, JSONObject data, FieldAttrEntity typeField) {
        Object itemValue = ItemUtil.getCustomItemList(typeField, data);
        String value = "";
        if (Objects.nonNull(itemValue)) {
            value = itemValue.toString();
        }
        communicateDetailPojo.setType(value);
    }

    /**
     * 设置范围筛选
     *
     * @param formDataListDTO
     * @throws
     * @author long.rao
     * @date 2020-03-03 10:04
     */
    private void rangeScreen(FormDataListDTO formDataListDTO) throws XbbException{
        JSONObject commonFilter = formDataListDTO.getCommonFilter();
        if (Objects.isNull(commonFilter)) {
            return;
        }
        JSONObject rangeScreen = commonFilter.getJSONObject(RangeScreenConstant.RANGE_SCREEN);
        if (Objects.isNull(rangeScreen) || Objects.isNull(rangeScreen.get(RangeScreenConstant.TYPE)) || StringUtil.isEmpty(rangeScreen.getString(RangeScreenConstant.TYPE)) || Objects.isNull(rangeScreen.get(RangeScreenConstant.VALUE))) {
            return;
        }

        String type;
        List<String> values;
        try {
            type = rangeScreen.getString(RangeScreenConstant.TYPE);
            values = rangeScreen.getJSONArray(RangeScreenConstant.VALUE).toJavaList(String.class);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), "customerCommunicateServiceimpl.rangeScreen中的commonFilter参数错误");
        }
        if (CollectionsUtil.isEmpty(values)) {
            return;
        }
        if (Objects.equals(type, RangeScreenConstant.DEPARTMENT)) {
            List<Long> deptIds = new ArrayList<>(values.size());
            values.forEach(item -> deptIds.add(Long.valueOf(item)));
            values = userModel.getUserIdsRecursionDep(deptIds, formDataListDTO.getCorpid(), 1, true);
        }

        List<ConditionsEntityExt> conditionsEntityExtList = formDataListDTO.getConditions();
        conditionsEntityExtList = conditionsEntityExtList == null ? new ArrayList<>() : conditionsEntityExtList;
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt(CustomerCommunicateEnum.CREATOR_ID.getAttr(), "",
                CustomerCommunicateEnum.CREATOR_ID.getFieldType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(values));
        conditionsEntityExtList.add(conditionsEntityExt);
        formDataListDTO.setConditions(conditionsEntityExtList);
    }
}
